package com.huangmb.anymark.server.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import com.huangmb.anymark.server.dto.Response;
import com.huangmb.anymark.server.model.Category;
import com.huangmb.anymark.server.model.CloudMap;
import com.huangmb.anymark.server.model.Marker;
import com.huangmb.anymark.server.model.User;
import com.huangmb.anymark.server.service.CloudMapService;
import com.huangmb.anymark.server.service.MarkerService;
import com.huangmb.anymark.server.utils.CloudMapUtils;
import com.huangmb.anymark.server.utils.Constant;
import com.huangmb.anymark.server.utils.Converter;
import com.huangmb.anymark.server.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.List;

/**
 * @author hmb
 * @version 1.0
 * @since 2016/5/3 23:29
 */
@RestController
@RequestMapping("/marker")
public class MarkerController {
    private static final Logger LOG = LoggerFactory.getLogger(MarkerController.class);
    @Resource(name = "markerService")
    private MarkerService mMarkerService;
    @Resource(name = "cloudMapService")
    private CloudMapService mCloudMapService;
    private SimplePropertyPreFilter mUserFilter = new SimplePropertyPreFilter(User.class, "id", "name");

    static {
        JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.DisableCircularReferenceDetect.getMask();
    }

    @RequestMapping(value = "/nearby", method = RequestMethod.GET)
    public Response nearby(@RequestParam Double latitude, @RequestParam Double longitude, @RequestParam Integer radius,
                           @RequestParam(required = false) Integer page, @RequestParam(required = false) String keyword,
                           @RequestParam(required = false) String filter) {
        if (latitude == null || longitude == null || radius == null) {
            return new Response(Response.CODE_BAD_PARAMETER, Response.MSG_BAD_PARAMETER, null);
        }
        page = page == null ? 1 : page;
        LOG.debug(radius + "关键字:"+keyword);
        List<Marker> markerList = CloudMapUtils.nearby(latitude, longitude, radius, keyword, filter, page);

        if (markerList == null) {
            return new Response(Response.CODE_BAD_PARAMETER, Response.MSG_BAD_PARAMETER, null);
        }
        //从本地数据库中再读取详细信息
        int n = markerList.size();
        if (n > 0) {
            Integer[] ids = new Integer[n];
            for (int i = 0; i < n; i++) {
                ids[i] = markerList.get(i).getId();
            }
            markerList = mMarkerService.getByIds(ids);
        }
        String result = JSON.toJSONString(markerList, mUserFilter);
        return Response.buildSuccess(result);

    }

    @RequestMapping(method = RequestMethod.POST)
    public Response create(Marker marker, HttpSession session) {
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        if (user == null) {
            LOG.debug("未登录");
            return new Response(Response.CODE_AUTH_FAIL, Response.MSG_AUTH_FAIL, null);
        }
        LOG.debug("title:" + marker.getTitle());
        marker.setCreateTime((int) (System.currentTimeMillis() / 1000L));
        marker.setUser(user);
        mMarkerService.save(marker);

        //这里需要将数据发到云图上存储用于搜索附近
        String id = CloudMapUtils.create(marker);
        CloudMap cloudMap = new CloudMap();
        cloudMap.setCloudId(id);
        cloudMap.setMarker(marker);
        mCloudMapService.save(cloudMap);
//\"category\":{\"description\":\"表示生活常见服务，如快递收发点，atm机等\",\"id\":1,\"name\":\"生活服务\"},\"createTime\":12343467,\"id\":1,\"info\":\"中通快递收发点\",\"latitude\":32.025665,\"longitude\":118.857077,\"title\":\"中通快递\"}
        return Response.buildSuccess(JSON.toJSONString(marker, mUserFilter));
    }

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    public Response getById(@PathVariable Integer id) {
        Marker marker = mMarkerService.getById(id);
        if (marker == null) {
            return new Response(Response.CODE_BAD_PARAMETER, Response.MSG_BAD_PARAMETER, null);
        }
        String res = JSON.toJSONString(marker, mUserFilter);
        return Response.buildSuccess(res);
    }

    @RequestMapping(value = "/list", params = {"action=my"}, method = RequestMethod.GET)
    public Response getMyMarkerList(HttpSession session) {

        User user = (User) session.getAttribute(Constant.SESSION_USER);
        if (user == null) {
            return new Response(Response.CODE_AUTH_FAIL, Response.MSG_AUTH_FAIL, null);
        }
        List<Marker> list = mMarkerService.getByUser(user.getId());
        String res = JSON.toJSONString(list, mUserFilter);
        return Response.buildSuccess(res);


    }

    /**
     * 通过id列表得到对应的标记（marker）集合
     *
     * @param ids id集合，用逗号隔开
     * @return response
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public Response getList(@RequestParam String ids) {
        System.out.println(ids + "\n\n\n");
        try {
            String[] array = ids.split(",");
            Integer[] intArray = new Integer[array.length];
            for (int i = 0; i < array.length; i++) {
                intArray[i] = Integer.valueOf(array[i]);
            }
            List<Marker> list = mMarkerService.getByIds(intArray);
            return Response.buildSuccess(JSON.toJSONString(list, mUserFilter));
        } catch (Exception e) {
            return new Response(Response.CODE_BAD_PARAMETER, Response.MSG_BAD_PARAMETER, null);
        }
    }

    /**
     * 修改一个marker
     *
     * @param marker 待修改内容
     * @return response
     */
    @RequestMapping(method = RequestMethod.PUT)
    public Response update(Marker marker, HttpSession session) {
        LOG.debug("marker: title:" + JSON.toJSONString(marker));

        Marker oldMarker = mMarkerService.getById(marker.getId());
        if (oldMarker == null) {
            return new Response(Response.CODE_BAD_PARAMETER, Response.MSG_BAD_PARAMETER, null);
        }
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        if (user == null || oldMarker.getUser().getId().intValue() != user.getId()) {
            return new Response(Response.CODE_AUTH_FAIL, Response.MSG_AUTH_FAIL, null);
        }
        if (StringUtils.isNotBlank(marker.getTitle())) {
            oldMarker.setTitle(marker.getTitle());
        }

        if (StringUtils.isNotBlank(marker.getInfo())) {
            oldMarker.setInfo(marker.getInfo());
        }
        if (StringUtils.isNotBlank(marker.getAddress())) {
            oldMarker.setAddress(marker.getAddress());
        }
        if (StringUtils.isNotBlank(marker.getCoverImage())) {
            oldMarker.setCoverImage(marker.getCoverImage());
        }
        if (marker.getLatitude() > 0.01) {
            oldMarker.setLatitude(marker.getLatitude());
        }
        if (marker.getLongitude() > 0.01) {
            oldMarker.setLongitude(marker.getLongitude());
        }
        mMarkerService.update(oldMarker);
        //TODO 更新云图
        CloudMap cloudMap = mCloudMapService.findByMarkerId(marker.getId());
        if (cloudMap != null){
            CloudMapUtils.update(oldMarker,cloudMap.getCloudId());
        }
        return Response.buildSuccess(JSON.toJSONString(oldMarker, mUserFilter));
    }

    @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    public Response delete(@PathVariable Integer id,HttpSession session){
        User user = (User) session.getAttribute(Constant.SESSION_USER);
        if(user == null){
            LOG.debug("未登录");
            return new Response(Response.CODE_AUTH_FAIL, Response.MSG_AUTH_FAIL, null);
        }
        Marker marker = mMarkerService.getById(id);
        if(marker != null && marker.getUser().getId().equals(user.getId())){
            CloudMap cloudMap = mCloudMapService.findByMarkerId(id);
            if(cloudMap != null){
                CloudMapUtils.delete(cloudMap.getCloudId());
                mCloudMapService.delete(cloudMap.getId());
            }
            mMarkerService.delete(id);
            return Response.buildSuccess(JSON.toJSONString(marker,mUserFilter));
        }
        return new Response(Response.CODE_BAD_PARAMETER,Response.MSG_BAD_PARAMETER,null);
    }
    @RequestMapping(value = "/category", method = RequestMethod.GET)
    public Response getAllCategory() {
        List<Category> list = mMarkerService.getAllCategory();
        String str = JSON.toJSONString(list);
        return Response.buildSuccess(str);
    }

}
